home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / XDME / Src / clipboard.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  11KB  |  545 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     clipboard.c
  5.  
  6.     DESCRIPTION
  7.     Provide standard clipboard.device interface functions like Open,
  8.     Close, Read, Write, etc.
  9.  
  10.     This is typed from "Amiga ROM Kernel Reference Manual: Devices"
  11.     Page 50 and following.
  12.  
  13.     NOTES
  14.     These functions are usefull for writing and reading simple FTXT.
  15.     Writing and reading complex FTXT, ILBM, etc. requires more work.
  16.     Under 2.0 it is highly recommended that you use iffparse.library.
  17.  
  18.     BUGS
  19.  
  20.     TODO
  21.  
  22.     EXAMPLES
  23.  
  24.     SEE ALSO
  25.  
  26.     INDEX
  27.  
  28.     HISTORY
  29.     29. May 1992    ada created
  30.  
  31. ******************************************************************************/
  32.  
  33. /* Includes */
  34. #include <exec/types.h>
  35. #include <exec/ports.h>
  36. #include <exec/io.h>
  37. #include <exec/memory.h>
  38. #include <devices/clipboard.h>
  39. #include "clipboard.h"
  40. #include <clib/exec_protos.h>
  41. #include <clib/alib_protos.h>
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include <string.h>
  45. #include <pragmas/exec_pragmas.h>
  46.  
  47. /* Globale Variable */
  48.  
  49. /* Interne Defines & Strukturen */
  50. /*#define DEBUG*/
  51.  
  52. /* Interne Variable */
  53.  
  54. /* Interne Prototypes */
  55. static int          ReadLong     (struct IOClipReq *, ULONG *);
  56. static struct cbbuf * FillCBData (struct IOClipReq *, ULONG);
  57.  
  58.  
  59. /*****************************************************************************
  60.  
  61.     NAME
  62.     CBOpen - Open the clipboard.device
  63.  
  64.     PARAMETER
  65.     ULONG unit;
  66.  
  67.     RESULT
  68.  
  69.     RETURN
  70.     struct IOClipReq * ior;     Initialized IOClipReq-structure or NULL
  71.  
  72.     DESCRIPTION
  73.     Opens the clipboard.device. A clipboard unit number must be passed in
  74.     as an argument. By default, the unit number should be 0 (currently
  75.     valid unit numbers are 0-255).
  76.  
  77.     NOTES
  78.  
  79.     BUGS
  80.  
  81.     EXAMPLES
  82.  
  83.     SEE ALSO
  84.  
  85.     INTERNALS
  86.  
  87.     HISTORY
  88.     29. May 1992    ada created
  89.  
  90. ******************************************************************************/
  91.  
  92. struct IOClipReq * CBOpen (ULONG unit)
  93. {
  94.     struct MsgPort * mp;
  95.     struct IOStdReq * ior;
  96.  
  97.     if (mp = CreatePort (NULL, NULL)) {
  98.     if (ior = (struct IOStdReq *)CreateExtIO (mp,
  99.         sizeof (struct IOClipReq))) {
  100.         if (!(OpenDevice ((STRPTR)"clipboard.device", unit,
  101.             (struct IORequest *)ior, NULL))) {
  102. #ifdef DEBUG
  103.     printf ("Open of clipboard.device unit %d successful\n", unit);
  104. #endif
  105.         return ((struct IOClipReq *)ior);
  106.         }
  107.     }
  108.     }
  109.  
  110. #ifdef DEBUG
  111.     printf ("No clipboard.device unit %d\n", unit);
  112. #endif
  113.  
  114.     return (NULL);
  115. } /* CBOpen */
  116.  
  117.  
  118. /*****************************************************************************
  119.  
  120.     NAME
  121.     CBClose - Close the clipboard.device
  122.  
  123.     PARAMETER
  124.     struct IOClipReq * ior;
  125.  
  126.     RESULT
  127.  
  128.     RETURN
  129.     void
  130.  
  131.     DESCRIPTION
  132.     Close the clipboard.device unit which was opened via CBOpen().
  133.  
  134.     NOTES
  135.  
  136.     BUGS
  137.  
  138.     EXAMPLES
  139.  
  140.     SEE ALSO
  141.  
  142.     INTERNALS
  143.  
  144.     HISTORY
  145.     29. May 1992    ada created
  146.  
  147. ******************************************************************************/
  148.  
  149. void CBClose (struct IOClipReq * ior)
  150. {
  151.     struct MsgPort * mp;
  152.  
  153.     mp = ior->io_Message.mn_ReplyPort;
  154.  
  155.     CloseDevice ((struct IORequest *)ior);
  156.     DeleteExtIO ((struct IORequest *)ior);
  157.     DeletePort (mp);
  158. } /* CBClose */
  159.  
  160.  
  161. /*****************************************************************************
  162.  
  163.     NAME
  164.     CBWriteFTXT - Write a string of text to the clipboard
  165.  
  166.     PARAMETER
  167.     struct IOClipReq * ior;
  168.     char         * string;
  169.  
  170.     RESULT
  171.  
  172.     RETURN
  173.     int success;        TRUE/FALSE
  174.  
  175.     DESCRIPTION
  176.     Write a NULL terminated string of text to the clipboard. The string
  177.     will be written in simple FTXT format.
  178.  
  179.     Note that this function pads odd length strings automatically to
  180.     conform to the IFF standard.
  181.  
  182.     NOTES
  183.  
  184.     BUGS
  185.  
  186.     EXAMPLES
  187.  
  188.     SEE ALSO
  189.  
  190.     INTERNALS
  191.  
  192.     HISTORY
  193.     29. May 1992    ada created
  194.  
  195. ******************************************************************************/
  196.  
  197. int CBWriteFTXT (struct IOClipReq * ior, char * string)
  198. {
  199.     ULONG length;    /* EVEN string-length */
  200.     ULONG slen;     /* length of string */
  201.     BOOL  odd;        /* ODD(slen) */
  202.     static ULONG IFF_header[] = {
  203.     ID_FORM,
  204.     0,
  205.     ID_FTXT,
  206.     ID_CHRS,
  207.     0
  208.     };
  209.  
  210.     slen = strlen (string);
  211.     odd  = slen & 1;
  212.  
  213.     length = odd ? slen+1 : slen;
  214.  
  215.     /* initial setup for Offset, Error and ClipID */
  216.     ior->io_Offset  = 0;
  217.     ior->io_Error   = 0;
  218.     ior->io_ClipID  = 0;
  219.  
  220.     /* Create the IFF-header information and write it */
  221.     IFF_header[1] = length + 12;
  222.     IFF_header[4] = slen;
  223.  
  224.     ior->io_Data    = (STRPTR)IFF_header;
  225.     ior->io_Length  = sizeof (IFF_header);
  226.     ior->io_Command = CMD_WRITE;
  227.     DoIO ((struct IORequest *)ior);
  228.  
  229.     /* write string itself */
  230.     ior->io_Data    = (STRPTR)string;
  231.     ior->io_Length  = length;           /* We can write slen+1 Bytes since
  232.                       a C-String always has a '\0'-Byte
  233.                       at his end. */
  234.     ior->io_Command = CMD_WRITE;
  235.     DoIO ((struct IORequest *)ior);
  236.  
  237.     /* Tell the clipboard we are done writing */
  238.     ior->io_Command = CMD_UPDATE;
  239.     DoIO ((struct IORequest *)ior);
  240.  
  241.     return (ior->io_Error ? FALSE : TRUE);
  242. } /* CBWriteFTXT */
  243.  
  244.  
  245. /*****************************************************************************
  246.  
  247.     NAME
  248.     CBQueryFTXT
  249.  
  250.     PARAMETER
  251.     struct IOClipReq * ior;
  252.  
  253.     RESULT
  254.  
  255.     RETURN
  256.     int result;        TRUE/FALSE
  257.  
  258.     DESCRIPTION
  259.     Check if the clipboard contains a FTXT.
  260.  
  261.     NOTES
  262.     If this function returns TRUE, you MUST either call CBReadCHRS()
  263.     until it returns FALSE or CBReadDone() to tell the clipboard.device
  264.     that we are done reading.
  265.  
  266.     BUGS
  267.  
  268.     EXAMPLES
  269.  
  270.     SEE ALSO
  271.  
  272.     INTERNALS
  273.  
  274.     HISTORY
  275.     29. May 1992    ada created
  276.  
  277. ******************************************************************************/
  278.  
  279. int CBQueryFTXT (struct IOClipReq * ior)
  280. {
  281.     ULONG cbuff[3];
  282.  
  283.     /* initial setup for Offset, Error and ClipID */
  284.     ior->io_Offset  = 0;
  285.     ior->io_Error   = 0;
  286.     ior->io_ClipID  = 0;
  287.  
  288.     /* Look for "FORM[size]FTXT" */
  289.     ior->io_Data    = (STRPTR)cbuff;
  290.     ior->io_Length  = 12;        /* 3*4 Bytes */
  291.     ior->io_Command = CMD_READ;
  292.     DoIO ((struct IORequest *)ior);
  293.  
  294.     /* Have we at least 12 bytes and a valid IFF-Header ? */
  295.     if (ior->io_Actual == 12L && cbuff[0] == ID_FORM && cbuff[2] == ID_FTXT) {
  296. #ifdef DEBUG
  297.     printf ("FTXT ok\n");
  298. #endif
  299.     return (TRUE);
  300.     }
  301.  
  302. #ifdef DEBUG
  303.     printf ("No FTXT\n");
  304. #endif
  305.  
  306.     CBReadDone (ior);
  307.     return (FALSE);
  308. } /* CBQueryFTXT */
  309.  
  310.  
  311. /*****************************************************************************
  312.  
  313.     NAME
  314.     CBReadCHRS
  315.  
  316.     PARAMETER
  317.     struct IOClipReq * ior;
  318.  
  319.     RESULT
  320.  
  321.     RETURN
  322.     struct cbbuf * cbbuf;        NULL on failure (out-of-memory or
  323.                     no more CHRS-chunks).
  324.  
  325.     DESCRIPTION
  326.     Reads and returns the text in the next CHRS chunk (if any) from the
  327.     clipboard.
  328.  
  329.     Allocates memory to hold data in next CHRS chunk.
  330.  
  331.     NOTES
  332.     The caller must free the returned buffer when done via CBFreeBuf().
  333.  
  334.     BUGS
  335.  
  336.     EXAMPLES
  337.  
  338.     SEE ALSO
  339.  
  340.     INTERNALS
  341.  
  342.     HISTORY
  343.     29. May 1992    ada created
  344.  
  345. ******************************************************************************/
  346.  
  347. struct cbbuf * CBReadCHRS (struct IOClipReq * ior)
  348. {
  349.     ULONG chunk;
  350.     ULONG size;
  351.     struct cbbuf * buf;
  352.  
  353.     /* Find next CHRS chunk */
  354.     buf = NULL;
  355.  
  356.     for (;;) {
  357.     if (!(ReadLong (ior, &chunk)) )
  358.         break;
  359.  
  360.     if (!(ReadLong (ior, &size)) )
  361.         break;
  362.  
  363.     /* if it is a CHRS-hunk */
  364.     if (chunk == ID_CHRS) {
  365. #ifdef DEBUG
  366.     printf ("Found CHRS\n");
  367. #endif
  368. #ifdef DEBUG
  369.     printf ("CHRS length = %d\n", size);
  370. #endif
  371.         if (size) { /* Read data */
  372.         buf = FillCBData (ior, size);
  373.         break;
  374.         }
  375.     } else { /* else skip this hunk */
  376.         if (size & 1)
  377.         size ++;
  378.  
  379.         ior->io_Offset += size;
  380.     }
  381.     }
  382.  
  383.     /* tell clipboard we are done */
  384.     if (!buf)
  385.     CBReadDone (ior);
  386.  
  387. #ifdef DEBUG
  388.     printf ("Found '%s'\n", buf->mem);
  389. #endif
  390.  
  391.     return (buf);
  392. } /* CBReadCHRS */
  393.  
  394.  
  395. static int ReadLong (struct IOClipReq * ior, ULONG * ldata)
  396. {
  397.     ior->io_Data    = (STRPTR)ldata;
  398.     ior->io_Length  = 4;
  399.     ior->io_Command = CMD_READ;
  400.  
  401.     DoIO ((struct IORequest *)ior);
  402.  
  403.     if (ior->io_Actual == 4 && !ior->io_Error)
  404.     return (TRUE);
  405.  
  406.     return (FALSE);
  407. }
  408.  
  409.  
  410. static struct cbbuf * FillCBData (struct IOClipReq * ior, ULONG size)
  411. {
  412.     register UBYTE * to;
  413.     register UBYTE * from;
  414.     register ULONG   t;
  415.     register ULONG   count;
  416.     struct cbbuf   * buf;
  417.  
  418.     if (!size)
  419.     return (NULL);
  420.  
  421.     if (size & 1)
  422.     size ++;
  423.  
  424.     if (buf = AllocMem (sizeof (struct cbbuf) + size, MEMF_PUBLIC)) {
  425.     buf->size = sizeof (struct cbbuf) + size;
  426.  
  427.     ior->io_Data    = (STRPTR)buf->mem;
  428.     ior->io_Length    = size;
  429.     ior->io_Command = CMD_READ;
  430.  
  431.     to = (UBYTE *)buf->mem;
  432.     count = NULL;
  433.  
  434.     if (!(DoIO ((struct IORequest *)ior)) && ior->io_Actual == size) {
  435.         for (t=0, from=to; t<size; t++) {
  436.         if (*from) {
  437.             *to ++ = * from;
  438.             count ++;
  439.         }
  440.  
  441.         from ++;
  442.         } /* for all bytes in the buffer */
  443.  
  444.         *to = 0;    /* terminate buffer with 0 */
  445.         buf->count = count;
  446.     } else { /* if DoIO && number of bytes */
  447.         FreeMem (buf, buf->size);
  448.         return (NULL);
  449.     }
  450.     }
  451.  
  452.     return (buf);
  453. } /* FillCBData */
  454.  
  455.  
  456. /*****************************************************************************
  457.  
  458.     NAME
  459.     CBReadDone - Tell clipboard we are done reading
  460.  
  461.     PARAMETER
  462.     struct IOClipReq * ior;
  463.  
  464.     RESULT
  465.  
  466.     RETURN
  467.     void
  468.  
  469.     DESCRIPTION
  470.     Reads past end of clipboard file until io_Actual is equal to 0. This
  471.     tells the clipboard that we are done reading.
  472.  
  473.     NOTES
  474.  
  475.     BUGS
  476.  
  477.     EXAMPLES
  478.  
  479.     SEE ALSO
  480.  
  481.     INTERNALS
  482.  
  483.     HISTORY
  484.     29. May 1992    ada created
  485.  
  486. ******************************************************************************/
  487.  
  488. void CBReadDone (struct IOClipReq * ior)
  489. {
  490.     char tmp_buffer[64];
  491.  
  492.     ior->io_Data    = (STRPTR)tmp_buffer;
  493.     ior->io_Length  = sizeof(tmp_buffer);
  494.     ior->io_Command = CMD_READ;
  495.  
  496.     /* falls through immediately if io_Actual == 0 */
  497.     while (ior->io_Actual) {
  498.     if (DoIO ((struct IORequest *)ior))
  499.         break;
  500.     }
  501.  
  502. } /* CBReadDone */
  503.  
  504.  
  505. /*****************************************************************************
  506.  
  507.     NAME
  508.     CBFreeBuf - Free buffer allocated by CBReadCHRS()
  509.  
  510.     PARAMETER
  511.     struct cbbuf * buf;
  512.  
  513.     RESULT
  514.  
  515.     RETURN
  516.     void
  517.  
  518.     DESCRIPTION
  519.     Frees a buffer allocated by CBReadCHRS().
  520.  
  521.     NOTES
  522.  
  523.     BUGS
  524.  
  525.     EXAMPLES
  526.  
  527.     SEE ALSO
  528.  
  529.     INTERNALS
  530.  
  531.     HISTORY
  532.     29. May 1992    ada created
  533.  
  534. ******************************************************************************/
  535.  
  536. void CBFreeBuf (struct cbbuf * buf)
  537. {
  538.     FreeMem (buf, buf->size);
  539. } /* CBFreeBuf */
  540.  
  541.  
  542. /******************************************************************************
  543. *****  ENDE clipboard.c
  544. ******************************************************************************/
  545.